package validate

import (
	"errors"
	"reflect"
	"strings"

	"github.com/go-playground/validator/v10"
)

type Validate interface {
	Check(any) error
}

type validateStruct struct {
	validate *validator.Validate
}

func New() Validate {
	return &validateStruct{
		validate: validator.New(),
	}
}

func (v validateStruct) Check(ba any) (errBase error) {
	ref := reflect.ValueOf(ba)
	validate := reflect.ValueOf(v.validate)
	methodExists := ref.MethodByName("Validate")
	if methodExists.String() != "<invalid Value>" && methodExists.Type().NumIn() == 1 && methodExists.Type().In(0) == validate.Type() {
		b := make([]reflect.Value, 0)
		b = append(b, validate)
		methodExists.Call(b)
	}

	defer func() {
		if err := recover(); err != nil {
			errBase = errors.New(err.(string))
		}
	}()

	if err := v.validate.Struct(ba); err != nil {
		for k, val := range err.(validator.ValidationErrors) {
			tag := reflect.TypeOf(ba)
			if field, ok := tag.Elem().FieldByName(val.StructField()); ok {
				if e := field.Tag.Get("validateErr"); e != "" {
					errSpic := strings.Split(e, ",")
					// for _, vs := range errSpic {
					// 	fieldSpic := strings.Split(vs, ":")
					// 	if fieldSpic[0] == val.ActualTag() {
					// 		return errors.New(fieldSpic[1])
					// 	}
					// }
					return errors.New(errSpic[k])
				}
				return err
			}
		}
	}

	return nil
}
